using UniversalAdminSystem.Application.Common.Interfaces;
using UniversalAdminSystem.Application.PermissionManagement.DTOs;
using UniversalAdminSystem.Application.PermissionManagement.Interfaces;
using UniversalAdminSystem.Domian.PermissionManagement.Aggregate;
using UniversalAdminSystem.Domian.PermissionManagement.IRepository;
using UniversalAdminSystem.Domian.PermissionManagement.ValueObjects;

namespace UniversalAdminSystem.Application.PermissionManagement.Services;

/// <summary>
/// 角色管理应用服务实现
/// 提供角色的创建、查询、更新、删除等业务操作的具体实现
/// </summary>
public class RoleManagementAppService : IRoleManagementAppService
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly IRoleRepository _roleRepository;
    private readonly IPermissionRepository _permissionRepository;

    public RoleManagementAppService(
        IUnitOfWork unitOfWork,
        IRoleRepository roleRepository,
        IPermissionRepository permissionRepository)
    {
        _unitOfWork = unitOfWork;
        _roleRepository = roleRepository;
        _permissionRepository = permissionRepository;
    }

    /// <summary>
    /// 获取所有角色列表
    /// </summary>
    public async Task<IEnumerable<RoleDto>> GetAllRolesAsync()
    {
        try
        {
            var roles = await _roleRepository.GetAllRolesWithPermissionsAsync();
            return roles.Select(r => new RoleDto(
                r.RoleId,
                r.Name,
                r.Description ?? string.Empty,
                r.IsSystem,
                r.IsSupper,
                r.CreateTime,
                r.UpdateTime,
                r.PermissionCount
            ));
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"获取角色列表失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 根据ID获取角色
    /// </summary>
    public async Task<RoleDto?> GetRoleByIdAsync(Guid roleId)
    {
        try
        {
            var role = await _roleRepository.GetRoleWithPermissionsAsync(roleId);
            if (role == null) return null;

            return new RoleDto(
                role.RoleId,
                role.Name,
                role.Description ?? string.Empty,
                role.IsSystem,
                role.IsSupper,
                role.CreateTime,
                role.UpdateTime,
                role.PermissionCount
            );
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"获取角色失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 创建新角色
    /// </summary>
    public async Task<RoleDto> CreateRoleAsync(RoleCreateDto createDto)
    {
        try
        {
            await _unitOfWork.BeginTransactionAsync();

            // 检查角色名称是否已存在
            if (await _roleRepository.ExistsAsync(createDto.Name))
            {
                throw new InvalidOperationException($"角色名称 '{createDto.Name}' 已存在");
            }

            // 创建角色
            var role = Role.Create(
                createDto.Name,
                createDto.Description,
                false,
                createDto.IsSupper
            );

            var savedRole = await _roleRepository.AddAsync(role);
            await _unitOfWork.CommitAsync();

            return new RoleDto(
                savedRole.RoleId,
                savedRole.Name,
                savedRole.Description,
                savedRole.IsSystem,
                savedRole.IsSupper,
                savedRole.CreateTime,
                savedRole.UpdateTime
            );
        }
        catch (Exception ex)
        {
            await _unitOfWork.RollbackAsync();
            throw new InvalidOperationException($"创建角色失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 更新角色信息
    /// </summary>
    public async Task<RoleDto> UpdateRoleAsync(Guid roleId, RoleUpdateDto updateDto)
    {
        try
        {
            await _unitOfWork.BeginTransactionAsync();

            var role = await _roleRepository.GetByGuidAsync(roleId);
            if (role == null)
            {
                throw new KeyNotFoundException($"角色ID '{roleId}' 不存在");
            }

            // 检查是否为系统角色
            if (role.IsSystem)
            {
                throw new InvalidOperationException("系统角色不允许修改");
            }

            // 检查角色名称是否已存在（排除当前角色）
            var existingRole = await _roleRepository.GetByNameAsync(updateDto.Name);
            if (existingRole != null && existingRole.RoleId != roleId)
            {
                throw new InvalidOperationException($"角色名称 '{updateDto.Name}' 已存在");
            }

            // 更新角色信息
            role.SetName(updateDto.Name);
            role.SetDescription(updateDto.Description);

            await _roleRepository.Update(role);
            await _unitOfWork.CommitAsync();

            return new RoleDto(
                role.RoleId,
                role.Name,
                role.Description,
                role.IsSystem,
                role.IsSupper,
                role.CreateTime,
                role.UpdateTime
            );
        }
        catch (Exception ex)
        {
            await _unitOfWork.RollbackAsync();
            throw new InvalidOperationException($"更新角色失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 删除角色
    /// </summary>
    public async Task DeleteRoleAsync(Guid roleId)
    {
        try
        {
            await _unitOfWork.BeginTransactionAsync();

            var role = await _roleRepository.GetByGuidAsync(roleId);
            if (role == null)
            {
                throw new KeyNotFoundException($"角色ID '{roleId}' 不存在");
            }

            // 检查是否为系统角色
            if (role.IsSystem)
            {
                throw new InvalidOperationException("系统角色不允许删除");
            }

            // 检查是否为超级管理员角色
            if (role.IsSupper)
            {
                throw new InvalidOperationException("超级管理员角色不允许删除");
            }

            await _roleRepository.RemoveAsync(roleId);
            await _unitOfWork.CommitAsync();
        }
        catch (Exception ex)
        {
            await _unitOfWork.RollbackAsync();
            throw new InvalidOperationException($"删除角色失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 为角色分配权限
    /// </summary>
    public async Task AssignPermissionsToRoleAsync(Guid roleId, IEnumerable<Guid> permissionIds)
    {
        try
        {
            await _unitOfWork.BeginTransactionAsync();

            var role = await _roleRepository.GetByGuidAsync(roleId);
            if (role == null)
            {
                throw new KeyNotFoundException($"角色ID '{roleId}' 不存在");
            }

            // 验证权限是否存在
            var permissions = await _permissionRepository.GetByIdsAsync(permissionIds);
            var validPermissionIds = permissions.Select(p => p.PermissionId).ToHashSet();
            var invalidPermissionIds = permissionIds.Except(validPermissionIds).ToList();

            if (invalidPermissionIds.Any())
            {
                throw new InvalidOperationException($"以下权限ID不存在: {string.Join(", ", invalidPermissionIds)}");
            }

            // 为角色分配权限（使用Permission实体）
            role.AddPermissions(permissions);

            await _roleRepository.Update(role);
            await _unitOfWork.CommitAsync();
        }
        catch (Exception ex)
        {
            await _unitOfWork.RollbackAsync();
            throw new InvalidOperationException($"为角色分配权限失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 移除角色的权限
    /// </summary>
    public async Task RemovePermissionsFromRoleAsync(Guid roleId, IEnumerable<Guid> permissionIds)
    {
        try
        {
            await _unitOfWork.BeginTransactionAsync();

            var role = await _roleRepository.GetByGuidAsync(roleId);
            if (role == null)
            {
                throw new KeyNotFoundException($"角色ID '{roleId}' 不存在");
            }

            // 获取要移除的权限实体
            var permissionsToRemove = await _permissionRepository.GetByIdsAsync(permissionIds);
            
            // 移除角色权限（使用Permission实体）
            role.RemovePermissions(permissionsToRemove);

            await _roleRepository.Update(role);
            await _unitOfWork.CommitAsync();
        }
        catch (Exception ex)
        {
            await _unitOfWork.RollbackAsync();
            throw new InvalidOperationException($"移除角色权限失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取角色的所有权限
    /// </summary>
    public async Task<IEnumerable<PermissionDto>> GetRolePermissionsAsync(Guid roleId)
    {
        var role = await _roleRepository.GetByGuidAsync(roleId);
        if (role == null)
        {
            throw new KeyNotFoundException($"角色ID '{roleId}' 不存在");
        }

        // 直接使用角色的权限导航属性
        return role.Permissions.Select(p => new PermissionDto(
            p.Name,
            p.Code,
            p.Description ?? string.Empty
        ));
    }
} 